#include <Math/Dual.h>
#include <iostream>
#include <sstream>

namespace BR
{
	template<class Tp, class CharT, class Traits>
	std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits> & istr, Dual<Tp> & rhs)
	{
		Tp rhs_re, rhs_im;
		CharT ch;
		istr >> ch;
		if (ch == '('){
			istr >> rhs_re >> ch;
			if (ch == ','){
				istr >> rhs_im >> ch;
				if (ch == ')') {
					rhs = Dual<Tp>(rhs_re, rhs_im);
				}
				else {
					istr.setstate(std::ios_base::failbit);
				}
			}
			else if (ch == ')'){
				rhs = rhs_re;
			}
			else {
				istr.setstate(std::ios_base::failbit);
			}
		}
		else{
			istr >> rhs_re;
			rhs = rhs_re;
		}
		return istr;
	}

	template<class Tp, class CharT, class Traits>
	std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits> & ostr, Dual<Tp> const & rhs)
	{
		std::basic_ostringstream<CharT, Traits> osstr;
		osstr.flags(ostr.flags());
		osstr.imbue(ostr.getloc());
		osstr.precision(ostr.precision());
		osstr << '(' << rhs.real << ',' << rhs.imag << ')';
		return ostr << osstr.str();
	}
}

